<script setup>
import { ref, onMounted, computed } from 'vue'
import { sessionApi, listDictsApi, pageTagsApi, saveTagApi, delTagsApi } from '@/commons/api'
import routes from '@/commons/router'
import Msg from '@/components/message'
import Confirm from '@/components/confirm'
import Pager from '@/components/pager/Pager.vue'
import { CScrollbar } from 'c-scrollbar'
import Loader from '@/components/loader/Loader.vue'
import { formatDate } from '@/commons/filter'

const actDict = ref({ dictId: '', dictName: '', dictCode: '' })
const loadShow = ref(false)

// 界面挂载前处理
onMounted(() => {
  // 获取用户会话信息
  checkAuth()
})

let procAuth = {
  addAuth: false,
  delAuth: false,
  edtAuth: false,
  pasAuth: false,
  unpAuth: false
}
// checkAuth 获取权限
const checkAuth = async () => {
  loadShow.value = true
  try {
    const res = await sessionApi()
    if(res.code === import.meta.env.VITE_SUCCESS_CODE) {
      const userBtnCode = res.data.btnCodes
      procAuth = {
        addAuth: userBtnCode.indexOf('1001010701') !== -1,
        delAuth: userBtnCode.indexOf('1001010702') !== -1,
        edtAuth: userBtnCode.indexOf('1001010703') !== -1,
      }
      await listDicts()
    } else {
      localStorage.removeItem("token")
      Msg({ kind: 'error', txt: res.msg })
      routes.replace('/login')
    }
    loadShow.value = false
  } catch (e) {
    loadShow.value = false
    Msg({ kind: 'error', txt: '系统异常，请联系管理员！' + e })
  }
}

const schRef = ref({
  keywords: '',
  kind: '',
  offset: 0,
  limit: 20
})
// listDicts 列表展示种类
const dictList = ref([])
const listDicts = async () => {
  const res = await listDictsApi({ kind: 2, typeCode: 'SYS_TAG' })
  if(res.code === import.meta.env.VITE_SUCCESS_CODE && res.data && res.data.length>0) {
    dictList.value = res.data
    actDict.value = { dictId: res.data[0].dictId, dictName: res.data[0].dictName, dictCode: res.data[0].dictCode }
    schRef.value.kind = res.data[0].dictCode
    await listTags(0, 1)
  } else {
    actDict.value = { dictId: '', dictName: '', dictCode: '' }
    dictList.value = []
    hasData.value = false
  }
}

// setDict 筛选数据字典项
const setDict = (dict) => {
  actDict.value = dict
  schRef.value.kind = dict.dictCode
  listTags(0, 1)
}

const total = ref(0)
const curPage = ref(1)
const tagList = ref([])
const hasData = ref(false)
// list 列表展示
const listTags = async (offset, cur) => {
  schRef.value.offset = offset || 0
  curPage.value = cur || 1
  hasData.value = false
  schRef.value.kind = actDict.value.dictCode
  loadShow.value = true
  try {
    const res = await pageTagsApi(schRef.value)
    if(res.code === import.meta.env.VITE_SUCCESS_CODE && res.data) {
      hasData.value = true
      total.value = res.data.total
      tagList.value = res.data.list
      idList.value = []
      checkList.value = []
      allCheck.value = false
      res.data.list.forEach(() => {
        checkList.value.push(false)
      })
    }
    loadShow.value = false
  } catch (e) {
    loadShow.value = false
    Msg({ kind: 'error', txt: '系统错误，请联系管理员！' + e })
  }
}

// search 筛选
const schShow = ref(false)
const search = () => {
  schShow.value = !schShow.value
}

// 选择效果实现
const idList = ref([])
const checkList = ref([])
const allCheck = ref(false)
// checkAll 全选
const checkAll = () => {
  idList.value = []
  checkList.value = []
  allCheck.value = !allCheck.value
  if(allCheck.value) {
    tagList.value.forEach(item => {
      idList.value.push(item.tagId)
      checkList.value.push(true)
    })
  } else {
    tagList.value.forEach(() => {
      checkList.value.push(false)
    })
  }
}
// checkCurId 单选
const checkCurId = (idx, tagId) => {
  if(!checkList.value[idx]) {
    idList.value.push(tagId)
  } else {
    idList.value.splice(idList.value.findIndex(id => id === tagId), 1)
  }
  checkList.value[idx] = !checkList.value[idx]
}

// clrSch 重置搜索框
const clrSch = () => {
  schRef.value = {
    keywords: '',
    kind: '',
    offset: 0,
    limit: 20
  }
  listTags(0, 1)
}

const tagForm = ref({
  tagId: '',
  tagName: '',
  kind: '',
})
// addTag 新增
const modalShow = ref(false)
const addTag = () => {
  if(actDict.value.dictCode === '') {
    Msg({ kind: 'warn', txt: '请先添加标签的种类' })
    return
  }
  modalShow.value = true
}
// updTag 修改
const updTag = async (curTag) => {
  modalShow.value = true
  tagForm.value.tagId = curTag.tagId
  tagForm.value.tagName = curTag.tagName
}
// saveTag 保存提交
const saveTag = async () => {
  let tagName = tagForm.value.tagName
  if(actDict.value.dictCode === '') {
    Msg({ kind: 'warn', txt: '请先添加标签的种类' })
    return
  } else if(tagName === '' || tagName.length > 80) {
    Msg({ kind: 'warn', txt: '标签的名称不能为空，且长度不超过80个字符' })
    return
  }
  tagForm.value.kind = actDict.value.dictCode
  loadShow.value = true
  try {
    const res = await saveTagApi(tagForm.value)
    if(res.code === import.meta.env.VITE_SUCCESS_CODE) {
      closeModal(2)
      await listTags(0, 1)
      Msg({ kind: 'success', txt: '恭喜您，标签信息保存成功！' })
    } else {
      Msg({ kind: 'error', txt: res.msg })
    }
    loadShow.value = false
  } catch (e) {
    loadShow.value = false
    Msg({ kind: 'error', txt: '系统错误，请联系管理员！' + e })
  }
}

// closeModal 关闭弹出层，并重置表单标签
const closeModal = () => {
  modalShow.value = false
  tagForm.value = {
    tagId: '',
    tagName: '',
    kind: '',
  }
}

// deletes 删除标签
const delTags = async() => {
  if(!idList || idList.value.length===0) {
    Msg({ kind: 'warn', txt: '请至少选择一项再操作！' })
    return
  }
  Confirm('确定要删除选中的标签吗？').then(() => {
    delTagsProc()
  }).catch(() => {
    Msg({ kind: 'info', txt: "取消处理选中的标签！" })
  })
}
// delTagsProc 删除标签实现，分离出来防止调用时异步报错
const delTagsProc = async () => {
  let tagIds = idList.value.join(',')
  loadShow.value = true
  try {
    const res = await delTagsApi({ tagIds })
    if(res.code === import.meta.env.VITE_SUCCESS_CODE) {
      await listTags(0, 1)
      Msg({ kind: 'success', txt: '恭喜您，标签信息删除成功！' })
    } else {
      Msg({ kind: 'error', txt: res.msg })
    }
    loadShow.value = false
  } catch (e) {
    loadShow.value = false
    Msg({ kind: 'error', txt: '系统错误，请联系管理员！' + e })
  }
}

// fmtDate 时间戳转时间
const fmtDate = computed(() => {
  return (time, kind) => {
    let date = new Date(time*1000)
    return formatDate(date, kind)
  }
})
</script>

<template>
  <div class="a">
    <div class="b">
      <div class="c">
        <div class="d">
          <div class="e">标签种类</div>
          <div v-if="procAuth.addAuth" class="btn-pi" title="新增" @click="addDict"><i class="iconfont">&#xea2d;</i> 新增</div>
        </div>
        <c-scrollbar class="f" v-if="dictList && dictList.length>0">
          <div v-for="curDict in dictList" :class="['g cur', actDict.dictCode===curDict.dictCode ? 'h' : '']" :key="curDict.dictId">
            <div class="i dan" @click="setDict(curDict)">{{ curDict.dictName }}[{{ curDict.dictCode }}]</div>
          </div>
        </c-scrollbar>
        <div v-else class="no-data">暂无内容</div>
      </div>
      <div class="j">
        <div class="k">
          <div class="l">
            <div v-if="procAuth.addAuth" class="btn-pi mr15" title="新增" @click="addTag"><i class="iconfont">&#xea2d;</i> 新增</div>
            <div v-if="procAuth.delAuth" class="btn-de mr15" title="删除" @click="delTags"><i class="iconfont">&#xea45;</i> 删除</div>
            <div class="btn-r mr15" title="筛选" @click="search"><i class="iconfont">&#xea49;</i></div>
            <div class="btn-r mr15" title="刷新" @click="listTags(0, 1)"><i class="iconfont">&#xea8c;</i></div>
          </div>
          <div class="m"><i class="iconfont">&#xeaaa;</i> 当前位置：工作台 > 系统管理 > 标签管理</div>
        </div>
        <div v-show="schShow" class="n">
          <div class="mr15 mt10"><input type="text" v-model="schRef.keywords" maxlength="30" placeholder="请输入关键字" class="sch-ipt" /></div>
          <div class="o mt10">
            <div class="btn-pi mr15" title="搜索" @click="listTags(0, 1)"><i class="iconfont">&#xea8e;</i> 搜索</div>
            <div class="btn-d" title="重置" @click="clrSch"><i class="iconfont">&#xea4f;</i> 重置</div>
          </div>
        </div>
        <div v-if="hasData">
          <table>
            <tbody>
            <tr>
              <th style="width: 5%;"><span @click="checkAll()" title="全选"><i :class="['iconfont', allCheck ? 'chked' : 'chk']" v-html="allCheck ? '&#xea3a;' : '&#xea46;'" /></span></th>
              <th style="width: 40%;">名称</th>
              <th style="width: 30%;">时间</th>
              <th style="width: 20%;">操作</th>
            </tr>
            <tr v-for="(curTag, index) in tagList" :key="curTag.tagId" class="tr-style">
              <td class="txt-center"><span @click="checkCurId(index, curTag.tagId)" title="选择"><i :class="['iconfont', checkList[index] ? 'chked' : 'chk']" v-html="checkList[index]  ? '&#xe685;' : '&#xe686;'" /></span></td>
              <td class="txt-center">{{curTag.tagName}}</td>
              <td class="txt-center">{{fmtDate(curTag.addTime, 2)}}</td>
              <td class="txt-center">
                <span v-if="procAuth.edtAuth" class="cl-warn" title="修改" @click="updTag(curTag)"><i class="iconfont">&#xea48;</i> 修 改</span>
              </td>
            </tr>
            </tbody>
          </table>
          <pager v-if="hasData" :limit="schRef.limit" :total="total" :page="curPage" @turn="listTags" />
        </div>
        <div v-else class="no-data">暂无内容</div>
      </div>
    </div>
    <!-- 新增、修改弹出层 -->
    <transition name="fade-mod" appear>
      <div v-if="modalShow" class="modal-backdrop">
        <c-scrollbar>
          <div class="modal" style="width: 600px;">
            <div class="modal-header">
              <div class="header-left"><i class="iconfont">&#xea54;</i> 保存标签信息</div>
              <div class="header-right" @click="closeModal"><i class="iconfont fs22">&#xea7f;</i></div>
            </div>
            <div class="modal-body">
              <div>
                <div class="ipt-title"><span class="required">*</span>标签名称</div>
                <div><input type="text" v-model="tagForm.tagName" maxlength="80" placeholder="请输入标签名称" class="ipt" /></div>
              </div>
            </div>
            <div class="modal-footer">
              <div class="btn-pi mr15" @click="saveTag"><i class="iconfont">&#xea90;</i> 保存</div>
              <div class="btn-d" @click="closeModal"><i class="iconfont">&#xea4f;</i> 取消</div>
            </div>
          </div>
        </c-scrollbar>
      </div>
    </transition>
    <loader :loadShow="loadShow" />
  </div>
</template>

<style scoped>
.a {width: 100%; height: 100%;}
.b {width: 100%; height: 100%; display: flex; display: -webkit-flex;}
.c {width: 279px; height: calc(100% - 20px); border-right: 1px solid #DDD; padding: 10px;}
.d {width: 100%; display: flex; display: -webkit-flex; margin-bottom: 10px; border-bottom: 1px solid #DDD;}
.e {flex-grow: 1; height: 35px; line-height: 35px; font-size: 16px;}
.f {height: calc(100% - 45px);}
.g {width: calc(100% - 20px); display: flex; display: -webkit-flex; background-color: #fafafa; padding: 0 10px; line-height: 35px; margin-bottom: 10px;}
.g:hover {background-color: #f2f2f2;}
.h {background-color: #EEE;}
.i {flex-grow: 1;}
.j {flex-grow: 1; padding: 10px;}
.k {padding: 0 20px 10px 20px; display: flex; display: -webkit-flex;}
.l {display: inline-flex; display: -webkit-inline-flex;}
.m {flex-grow: 1; text-align: right; padding-top: 10px; color: #666;}
.n {border: 1px dashed #DDD; padding: 5px 15px 15px 15px; display: flex; display: -webkit-flex; flex-wrap: wrap; margin-bottom: 10px;}
.o {display: inline-flex; display: -webkit-inline-flex;}
</style>